import React, { useState, useRef, useEffect } from "react";
import { assign } from 'lodash';

import type { RawData } from '../index';

import { Popover, Tooltip } from 'antd';
import { CheckCircleOutlined } from '@ant-design/icons';

export type Unit = {
  dealDate: number | null;
  memo: string;
  operate: string;
  user: string;
}

interface renderOptions {
  isApproved: boolean; // 当前节点是否已经完成审批；
  isApproving: boolean; // 当前节点是否正在审批： 当节点处于待审批阶段且审批人包含当前登陆人时为true
}

interface RenderFunction {
  (row: any, options: renderOptions): React.ReactNode
}

export interface ProcessNodeProps {
  container: HTMLDivElement;
  current?: boolean; // 当前节点是否是当前用户审批中
  visible?: boolean | ((data: RawData) => boolean);
  trigger?: 'click' | 'hover';
  disabled?: boolean; // 是否禁用弹出气泡， 当设置位true时， 不会显示气泡
  popoverContentRender?: RenderFunction; // 气泡自定义render函数
  // 自定义审批节点icon，自定义之后需要配置 ParallerFlow.graphProps.connecting.anchor 选项， 否则节点连接线会偏离；如果没有偏离可以不设置
  iconRender?: RenderFunction;
  extraRender?: RenderFunction; // 节点下方的说明内容
  data: RawData;
  isApproved?: (data: RawData) => boolean;
  showLabel?: boolean;
}

const ProcessNode = (props: ProcessNodeProps) => {
  const {
    container,
    current = false,
    trigger = 'hover',
    popoverContentRender,
    iconRender,
    extraRender,
    data,
    isApproved,
    showLabel = true
  } = props;

  const { units, node: label, type } = data;

  const timerRef = useRef<any>();
  const popoverRef = useRef<any>();
  const [visible, setVisble] = useState(false);
  const hasApproved = typeof isApproved === 'function' ? isApproved(data) : units.some((unit) => unit.dealDate);

  const toggleVisible = (v: any) => {
    if(props.disabled){
      // 禁用之后不显示气泡；
      setVisble(false);
    }else if(v){
      setVisble(v && hasApproved);
    }else{
      timerRef.current = setTimeout(() => {
        setVisble(false);
      }, 100);
    }
  }

  const clearTimer = () => {
    clearTimeout(timerRef.current);
  };

  const replaceMemo = () => {
    const result = units.find((item) => item.dealDate);
    if(result){
      let div: HTMLElement | null = document.createElement('div');
      div.innerHTML = result.memo.replace(/\\n/g, '<br/>');
      result.memo = div.innerText;
      div = null;
    }
    return result;
  }

  const unit = replaceMemo();

  let iconDom: React.ReactNode = <div className={current ? 'current_node': 'unapproved'}/>;

  if(typeof iconRender === 'function'){
    iconDom = iconRender(data, { isApproved: hasApproved, isApproving: current });
  }else if(hasApproved){
    iconDom = (
      <CheckCircleOutlined style={{ marginLeft: '8px', marginRight: '8px', fontSize: '32px', color: '#1890FF' }}/>
    );
  }

  let extraDom: React.ReactNode;

  if(typeof extraRender === 'function'){
    extraDom = extraRender(data, { isApproved: hasApproved, isApproving: current })
  }else{
    extraDom = (
      <>
        {
          type !== 'UserTask' && hasApproved && (
            <div className='flex flex_column no_popover'>
              <span className='fields field_grey'>
                <span dangerouslySetInnerHTML={unit ? { __html: unit.memo } : undefined}></span>
              </span>
              <span className='fields field_grey'>
                <span>{hasApproved ? new Date(unit!.dealDate!).toLocaleDateString() : ''}</span>
              </span>
            </div>
          )
        }
        {
          current && (
            <div className='flex flex_column no_popover'>
              <span className='fields field_grey'>
                审批人：<span>{units.map((item) => item.user).join('/')}</span>
              </span>
              <span className='fields field_grey'>审核中...</span>
            </div>
          )
        }
      </>
    )
  }

  useEffect(() => {
    const onPopupMouseEnter = popoverRef.current?.onPopupMouseEnter;
    const onPopupMouseLeave = popoverRef.current?.onPopupMouseLeave;
    assign(popoverRef.current, {
      onPopupMouseEnter: (...rest) => {
        onPopupMouseEnter?.(...rest);
        clearTimer();
      },
      onPopupMouseLeave: (...rest) => {
        onPopupMouseLeave?.(...rest);
        if (trigger === 'hover') toggleVisible(false);
      }
    })
    // 组件销毁清除延时器
    return clearTimer;
  }, []);

  let popoverVisible = visible;

  if('visible' in props){
    popoverVisible = typeof props.visible === 'function' ? props.visible(data) : props.visible;
  }

  return (
    <Popover
      ref={popoverRef}
      visible={popoverVisible}
      placement="bottomLeft"
      autoAdjustOverflow={false}
      content={() => {
        if(typeof popoverContentRender === 'function'){
          return popoverContentRender(data, { isApproved: hasApproved, isApproving: current })
        }
        return (
          <div className='flex flex_column popover'>
            <span className='fields'>
              审批人：<span>{unit?.user}</span>
            </span>
            <span className="fields">
              开始时间：
              <span>{hasApproved ? new Date(unit!.dealDate!).toLocaleDateString : ''}</span>
            </span>
            <span className='fields comment'>
              审批意见：
              {hasApproved && unit!.memo.length! > 40 ? (
                <Tooltip title={unit?.memo}>
                  <span>{unit?.memo}</span>
                </Tooltip>
              ) : (
                <span>{unit?.memo}</span>
              )}
            </span>
          </div>
        )
      }}
      getPopupContainer={() => container}
    >
      <>
        <div
          className="flex flex_align_center"
          onMouseEnter={() => {
            clearTimer();
            if(trigger === 'hover') toggleVisible(true);
          }}
          onMouseLeave={() => {
            if(trigger === 'hover') toggleVisible(false);
          }}
          onClick={() => {
            if(trigger === 'click') toggleVisible(!visible);
          }}
        >
          {iconDom}
          {showLabel && <span className="node_label">{label}</span>}
        </div>
      </>
    </Popover>
  )
}


export default ProcessNode;
